package org.com.Service.Impl;

import Entity.Comment;
import Entity.Community;
import Entity.Postlike;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.com.FeignClient.CommentFeign;
import org.com.FeignClient.PostlikeFeign;
import org.com.Mapper.CommunityMapper;
import org.com.Service.ICommunityService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 277
 * @since 2025-10-04
 */
@Slf4j
@Service
public class CommunityServiceImpl extends ServiceImpl<CommunityMapper, Community> implements ICommunityService {

    @Autowired
    private PostlikeFeign postlikeFeign;

    @Autowired
    private StringRedisTemplate redis;

    @Autowired
    private CommentFeign commentFeign;

    @Override
    public List<Community> getall() {
        return this.list();
    }


    @Transactional
    @Override
    public Map<String, Object> up(Map<String, Object> communitys) {

        Object communityid = communitys.get("postId");
        Object userid = communitys.get("userId");

/**通过postlike 对比当前用户和帖子 是否点过赞*/

        int communi = Integer.parseInt(communitys.get("postId").toString());
        int use = Integer.parseInt(communitys.get("userId").toString());

        Postlike postlike = new Postlike();
        postlike.setLikeId(communi);
        postlike.setUserlikeId(use);

        //调用检查方法
        Boolean down = postlikeFeign.down(postlike);
        HashMap<String, Object> map = new HashMap<>();

        /**
         *  根据postlike的返回值判断是否重复点赞
         *  如果false 则执行点赞 记录数据库
         */
        if (!down) {
            boolean update = lambdaUpdate().eq(Community::getId, communityid)
                    .setSql("like_member=like_member+1")
                    .update();

            log.info("点赞成功");
            map.put("success", update);

            postlikeFeign.save(postlike);
            if (update) {
                Community community = getById((Serializable) communityid);
//                redis.opsForZSet().add("community:like", communityid.toString(), community.getLikeMember());

                upscorewithredis(community);
                saveWithredis(community);

            }


        } else {
            //重复点赞 执行取消点赞 取消数据库记录
            log.info("重复点赞");
            map.put("success", false);
            down(postlike);
        }
        //写入redis


        return map;
    }

    private void upscorewithredis(Community community) {
        int like_member_score = 10;
        int comment_member_score = 5;


        int allsocre = (int) (community.getLikeMember() * like_member_score + community.getCommentMember() * comment_member_score);


        redis.opsForZSet().add("community:like", String.valueOf(community.getId()), allsocre);


    }

    private void saveWithredis(Community community) {
        log.info("查到数据:{}", community);

        log.info("redis写入博客开始");
        Map<String, Object> communityMap = BeanUtil.beanToMap(community, false, true);
        Map<String, Object> redisMap = new HashMap<>();
        for (Map.Entry<String, Object> entry : communityMap.entrySet()) {
            if (entry.getKey() != null) {
                redisMap.put(entry.getKey(), entry.getValue().toString());
            }
        }
        redis.opsForHash().putAll("community:" + community.getId(), redisMap);
        redis.expire("community:" + community.getId(), 24, TimeUnit.HOURS);

    }

    @Transactional
    @Override
    public String down(Postlike postlike) {

        boolean update = lambdaUpdate().eq(Community::getId, postlike.getLikeId())
                .setSql("like_member=like_member-1")
                .update();

        if (update) {
            postlikeFeign.deletebyid(postlike);

            Community community = getById(postlike.getLikeId());
            if (community != null) {
//                redis.opsForZSet().add("community:like", postlike.getLikeId().toString(), community.getLikeMember());
                upscorewithredis(community);
            }
            saveWithredis(community);
        }
        return "取消点赞成功";

    }

    @Override
    public List<Community> host() {
        List<Community> communitilist = new ArrayList<>();
        Set<String> range = redis.opsForZSet().reverseRange("community:like", 0, 9);
        List<Integer> ids = range.stream().map(Integer::parseInt).collect(Collectors.toList());
        communitilist = this.listByIds(ids);

        List<Community> sortedbyredis = sortedbyredis(communitilist, ids);


        return sortedbyredis;
    }

    @Override
    public List<Comment> comment(Map<String, Object> community) {

        Object postId = community.get("postId");
        Object userId = community.get("userId");
        Object content = community.get("content");


        int postid = Integer.parseInt(postId.toString());
        int userid = Integer.parseInt(userId.toString());


        Comment comment = new Comment();
        comment.setCommentUserid(userid);
        comment.setPostid(postid);
        comment.setContent(content.toString());
        Boolean save = commentFeign.save(comment);


        if (save) {
            boolean update = lambdaUpdate().eq(Community::getId, postId)
                    .setSql("comment_member=comment_member+1")
                    .update();

            if (update) {

                LambdaQueryWrapper<Community> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(Community::getId, postId);
                Community one = getOne(wrapper);
                upscorewithredis(one);
            }
        }


        List<Comment> comments = new ArrayList<>();
        comments.add(comment);

        return comments;
    }

    private List<Community> sortedbyredis(List<Community> communitilist, List<Integer> ids) {

        Map<Integer, Community> communityMap = communitilist.stream().collect(Collectors.toMap(Community::getId, Community -> Community));
        List<Community> sorted = new ArrayList<>();
        for (Integer id : ids) {
            Community community = communityMap.get(id);
            if (community != null) {
                sorted.add(community);
            }
        }
        return sorted;
    }


}

